const fs = require('fs')
const path = require('path')
const url = require('url')
const qs = require('querystring')
const { access } = require('./utils/log')
const { getPostData, getCookieExpires, parseCokie, parseSession, parseSessionWithRedis } = require('./utils/tools')
const handleBlogRoute = require('./router/blog')
const handleUserRoute = require('./router/user')

function serverHandle(req, res) {
  // 记录 access log
  access(`${req.method} -- ${req.url} -- ${req.headers['user-agent']} -- ${Date.now()}`)

  // 设置返回格式 JSON
  res.setHeader('Content-type', 'application/json')

  // 处理 url 和 解析参数
  let objUrl = url.parse(req.url)
  req.path = objUrl.pathname
  req.query = qs.parse(objUrl.query)
  req.method = req.method.toUpperCase()

  // 解析 cookie
  parseCokie(req)

  // 解析 session (不使用 redis)
  // let { userId, needSetCookie } = parseSession(req)

  // 解析 session (使用 redis)，解析完 session 后在执行后面的操作，避免执行 loginCheck 函数时报错
  parseSessionWithRedis(req).then(({ userId, needSetCookie }) => {
    // 处理 post data
    getPostData(req).then(postData => {
      req.body = postData

      // 处理 blog 路由
      const blogResult = handleBlogRoute(req, res)
      if (blogResult) {
        blogResult.then(data => {
          if (needSetCookie) {
            res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
          }
          res.end(JSON.stringify(data))
        })
        return
      }

      // 处理 user 路由
      const userResult = handleUserRoute(req, res)
      if (userResult) {
        userResult.then(data => {
          if (needSetCookie) {
            res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
          }
          res.end(JSON.stringify(data))
        })
        return
      }

      // 获取静态资源
      const filename = req.path === '/' ? 'index.html' : req.path.substring(1)

      var type = (function(_type) {
        switch (
          _type // 扩展名
        ) {
          case 'html':
          case 'htm':
            return 'text/html;charset=UTF-8'
          case 'js':
            return 'application/javascript;charset=UTF-8'
          case 'css':
            return 'text/css;charset=UTF-8'
          case 'txt':
            return 'text/plain;charset=UTF-8'
          case 'manifest':
            return 'text/cache-manifest;charset=UTF-8'
          default:
            return 'application/octet-stream'
        }
      })(filename.substring(filename.lastIndexOf('.') + 1))

      fs.readFile(path.resolve(__dirname, `../client/${filename}`), function(err, content) {
        if (err) {
          // 处理404
          res.writeHead(404, { 'Content-type': 'text/plain;charset=UTF-8' })
          res.write('404 Not Found')
          res.end()
        } else {
          res.writeHead(200, { 'Content-type': type })
          res.write(content)
        }
        res.end()
      })
    })
  })
}

module.exports = serverHandle
